x86: Allow exceptions to be handled while interrupts are
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Wed, 21 Feb 2007 10:13:40 +0000 (10:13 +0000)
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Wed, 21 Feb 2007 10:13:40 +0000 (10:13 +0000)
disabled. Handlers must take special care if necessary.
Fixes the debug 'd' key.
Signed-off-by: Keir Fraser <keir@xensource.com>
xen/arch/x86/traps.c
xen/arch/x86/x86_32/entry.S
xen/arch/x86/x86_64/entry.S

index 3eff302b7e1c029b033d7931d8dacac907fdfa68..145056e49c0f86adc503e12ca6f88e02f0bb4f4f 100644 (file)
@@ -625,7 +625,8 @@ asmlinkage int do_invalid_op(struct cpu_user_regs *regs)
     if ( unlikely(!guest_mode(regs)) )
     {
         struct bug_frame bug;
-        if ( (__copy_from_user(&bug, (char *)regs->eip, sizeof(bug)) == 0) &&
+        if ( is_kernel(regs->eip) &&
+             (__copy_from_user(&bug, (char *)regs->eip, sizeof(bug)) == 0) &&
              (memcmp(bug.ud2, "\xf\xb",    sizeof(bug.ud2)) == 0) &&
              (memcmp(bug.mov, BUG_MOV_STR, sizeof(bug.mov)) == 0) &&
              (bug.ret == 0xc2) )
@@ -877,6 +878,9 @@ static int fixup_page_fault(unsigned long addr, struct cpu_user_regs *regs)
         return 0;
     }
 
+    ASSERT(!in_irq());
+    ASSERT(regs->eflags & X86_EFLAGS_IF);
+
     if ( VM_ASSIST(d, VMASST_TYPE_writable_pagetables) &&
          guest_kernel_mode(v, regs) &&
          /* Do not check if access-protection fault since the page may 
@@ -904,8 +908,6 @@ asmlinkage int do_page_fault(struct cpu_user_regs *regs)
     unsigned long addr, fixup;
     int rc;
 
-    ASSERT(!in_irq());
-
     addr = read_cr2();
 
     DEBUGGER_trap_entry(TRAP_page_fault, regs);
@@ -1916,6 +1918,8 @@ void unset_nmi_callback(void)
 
 asmlinkage int math_state_restore(struct cpu_user_regs *regs)
 {
+    BUG_ON(!guest_mode(regs));
+
     setup_fpu(current);
 
     if ( current->arch.guest_context.ctrlreg[0] & X86_CR0_TS )
index 286c4b5fb7b20898e39277a4759ee3760faac86d..1de36aa3e763edcb274d1a675a3f4c036eb6e864 100644 (file)
@@ -424,7 +424,7 @@ handle_exception:
         testb $X86_EFLAGS_IF>>8,UREGS_eflags+1(%esp)
         jz    exception_with_ints_disabled
         sti                             # re-enable interrupts
-        xorl  %eax,%eax
+1:      xorl  %eax,%eax
         movw  UREGS_entry_vector(%esp),%ax
         movl  %esp,%edx
         pushl %edx                      # push the cpu_user_regs pointer
@@ -451,7 +451,7 @@ exception_with_ints_disabled:
         call  search_pre_exception_table
         addl  $4,%esp
         testl %eax,%eax                 # no fixup code for faulting EIP?
-        jz    FATAL_exception_with_ints_disabled
+        jz    1b
         movl  %eax,UREGS_eip(%esp)
         movl  %esp,%esi
         subl  $4,%esp
index 36b5c5e1ad3122e40dbf77c43602067e63c67cff..cffd89dcede0fd993ea364dd9232ac5459be5ee2 100644 (file)
@@ -362,7 +362,7 @@ ENTRY(handle_exception)
         testb $X86_EFLAGS_IF>>8,UREGS_eflags+1(%rsp)
         jz    exception_with_ints_disabled
         sti
-        movq  %rsp,%rdi
+1:      movq  %rsp,%rdi
         movl  UREGS_entry_vector(%rsp),%eax
         leaq  exception_table(%rip),%rdx
         GET_CURRENT(%rbx)
@@ -388,7 +388,7 @@ exception_with_ints_disabled:
         movq  %rsp,%rdi
         call  search_pre_exception_table
         testq %rax,%rax                 # no fixup code for faulting EIP?
-        jz    FATAL_exception_with_ints_disabled
+        jz    1b
         movq  %rax,UREGS_rip(%rsp)
         subq  $8,UREGS_rsp(%rsp)        # add ec/ev to previous stack frame
         testb $15,UREGS_rsp(%rsp)       # return %rsp is now aligned?